package org.nvframe.component.pickup;

import org.nvframe.component.AbstractComponent;
import org.nvframe.component.property.PropertyManager;
import org.nvframe.entity.Entity;
import org.nvframe.event.EventService;
import org.nvframe.event.eventtype.CollisionEvent;
import org.nvframe.event.eventtype.CollisionListener;
import org.nvframe.event.eventtype.StatsEvent;
import org.nvframe.exception.NVFrameException;
import org.nvframe.manager.ConfigManager;
import org.nvframe.util.Settings;

/**
 * 
 * @author Nik Van Looy
 *
 */
public class PickupableImpl extends AbstractComponent implements Pickupable, CollisionListener {
	
	private String affectsProperty;
	private String affectOperation;
	private int affectsValue;
	private boolean removeOnCollision;
	
	public PickupableImpl(String id, Entity owner, Settings settings) throws NVFrameException {
		super(id, owner);
		
		removeOnCollision = settings.getBoolean("removeOnCollision", true);
		affectsProperty = settings.getString("affectsProperty", null);
		affectOperation = settings.getString("affectOperation", null);
		affectsValue = settings.getInt("affectsValue", 0);
		
		if(affectsProperty == null || affectOperation == null)
			throw new NVFrameException("cannot instantiate PickupableImpl component without " +
					"a affectsProperty or affectOperation in settings [entityid: " + owner.getId() + "]");

		EventService.getInstance().addEventListener(this);
	}

	/**
	 * Set the transient property of a given Entity
	 * 
	 * @param entity The Entity who receives the pickup
	 */
	private void setPropertyTo(Entity receiver) {
		PropertyManager entPropManager = (PropertyManager) receiver.getComponent(PropertyManager.class);
		
		if(affectOperation.equals("add"))
			entPropManager.getPropertyInt(affectsProperty).add(affectsValue);
		else if(affectOperation.equals("substract"))
			entPropManager.getPropertyInt(affectsProperty).substract(affectsValue);
		else if(affectOperation.equals("multiply"))
			entPropManager.getPropertyInt(affectsProperty).multiply(affectsValue);
		else if(affectOperation.equals("percentage"))
			entPropManager.getPropertyInt(affectsProperty).percentage(affectsValue);
			
	}
	
	@Override
	public void onCollision(CollisionEvent event) {
		Entity receiver = null;
		
		// determine the receiving entity
		if(event.getEntity1() == owner)
			receiver = event.getEntity2();
		else
			receiver = event.getEntity1();
		
		if(!receiver.hasComponent(PropertyManager.class))
			return;

		// set the property affected by this pickup
		setPropertyTo(receiver);
		EventService.getInstance().fireEvent(new StatsEvent(affectsProperty), receiver);
		
		if(ConfigManager.getInstance().getActive("debugMode"))
			System.out.println("entity "+ receiver.getId() + " got a pick-up | affectedProperty: " + 
					affectsProperty + " | operation: " + affectOperation + " | quantity: " + affectsValue);
		
		// remove the pickup item on collision
		if(removeOnCollision)
			owner.removed();
	}
	
	@Override
	public void removed(Entity entity) {
		EventService.getInstance().removeEventListener(this);
	}
}
